
from sentinelsat import SentinelAPI
from tkinter import filedialog
from tkinter import scrolledtext
from subprocess import Popen
import tkinter as tk
import tkinter.ttk
import threading
import calendar
import paramiko 
import datetime
import pathlib
import time
import re
import os


china_tiles = {
	"请选择省份（非必须）" : [],
    "浙江省": [
        "50RQV",
        "50RPU",
        "50RQU",
        "50RNT",
        "50RPT",
        "50RQT",
        "50RPS",
        "50RQS",
        "50RPR",
        "50RQR",
        "51RTQ",
        "51RUQ",
        "51RTP",
        "51RUP",
        "51RVP",
        "51RTN",
        "51RUN",
        "51RVN",
        "51RTM",
        "51RUM",
        "51RTL",
        "51RUL"
    ],
    "云南省": [
        "48QTM",
        "48QUM",
        "48QVM",
        "48QWM",
        "48QXM",
        "48QTL",
        "48QUL",
        "48QVL",
        "48QWL",
        "48QXL",
        "48QTK",
        "48QUK",
        "48RUS",
        "48RVS",
        "48RWS",
        "48RTR",
        "48RUR",
        "48RVR",
        "48RWR",
        "48RTQ",
        "48RUQ",
        "48RVQ",
        "48RTP",
        "48RUP",
        "48RVP",
        "48RTN",
        "48RUN",
        "48RVN",
        "48RWN",
        "47QLG",
        "47QMG",
        "47QNG",
        "47QPG",
        "47QQG",
        "47QRG",
        "47QMF",
        "47QNF",
        "47QPF",
        "47QQF",
        "47QRF",
        "47QNE",
        "47QPE",
        "47QQE",
        "47QRE",
        "47QPD",
        "47QQD",
        "47RMN",
        "47RNN",
        "47RMM",
        "47RNM",
        "47RPM",
        "47RML",
        "47RNL",
        "47RPL",
        "47RQL",
        "47RMK",
        "47RNK",
        "47RPK",
        "47RQK",
        "47RMJ",
        "47RNJ",
        "47RPJ",
        "47RQJ",
        "47RRJ",
        "47RLH",
        "47RMH",
        "47RNH",
        "47RPH",
        "47RQH",
        "47RRH"
    ],
    "新疆": [
        "43SCD",
        "43SDD",
        "43SED",
        "43SFD",
        "43SGD",
        "43SCC",
        "43SDC",
        "43SEC",
        "43SFC",
        "43SGC",
        "43SDB",
        "43SEB",
        "43SFB",
        "43SGB",
        "43SDA",
        "43SEA",
        "43SFA",
        "43SGA",
        "43SEV",
        "43SFV",
        "43SGV",
        "43TEF",
        "43TFF",
        "43TGF",
        "43TDE",
        "43TEE",
        "43TFE",
        "43TGE",
        "44SKJ",
        "44SLJ",
        "44SMJ",
        "44SNJ",
        "44SPJ",
        "44SQJ",
        "44SKH",
        "44SLH",
        "44SMH",
        "44SNH",
        "44SPH",
        "44SQH",
        "44SKG",
        "44SLG",
        "44SMG",
        "44SNG",
        "44SPG",
        "44SQG",
        "44SKF",
        "44SLF",
        "44SMF",
        "44SNF",
        "44SPF",
        "44SQF",
        "44SKE",
        "44SLE",
        "44SME",
        "44SNE",
        "44SPE",
        "44SQE",
        "44SKD",
        "44SLD",
        "44SMD",
        "44SND",
        "44TPT",
        "44TQT",
        "44TPS",
        "44TQS",
        "44TMR",
        "44TNR",
        "44TPR",
        "44TQR",
        "44TMQ",
        "44TNQ",
        "44TPQ",
        "44TQQ",
        "44TMP",
        "44TNP",
        "44TPP",
        "44TQP",
        "44TMN",
        "44TNN",
        "44TPN",
        "44TQN",
        "44TLM",
        "44TMM",
        "44TNM",
        "44TPM",
        "44TQM",
        "44TKL",
        "44TLL",
        "44TML",
        "44TNL",
        "44TPL",
        "44TQL",
        "44TKK",
        "44TLK",
        "44TMK",
        "44TNK",
        "44TPK",
        "44TQK",
        "45STD",
        "45SUD",
        "45SVD",
        "45SWD",
        "45SXD",
        "45SYD",
        "45STC",
        "45SUC",
        "45SVC",
        "45SWC",
        "45SXC",
        "45SYC",
        "45STB",
        "45SUB",
        "45SVB",
        "45SWB",
        "45SXB",
        "45SYB",
        "45STA",
        "45SUA",
        "45SVA",
        "45SWA",
        "45SXA",
        "45SYA",
        "45STV",
        "45SUV",
        "45SVV",
        "45SYV",
        "45TUN",
        "45TVN",
        "45TWN",
        "45TXN",
        "45TYN",
        "45TUM",
        "45TVM",
        "45TWM",
        "45TXM",
        "45TYM",
        "45TUL",
        "45TVL",
        "45TWL",
        "45TXL",
        "45TYL",
        "45TUK",
        "45TVK",
        "45TWK",
        "45TXK",
        "45TYK",
        "45TUJ",
        "45TVJ",
        "45TWJ",
        "45TXJ",
        "45TYJ",
        "45TUH",
        "45TVH",
        "45TWH",
        "45TXH",
        "45TYH",
        "45TUG",
        "45TVG",
        "45TWG",
        "45TXG",
        "45TYG",
        "45TTF",
        "45TUF",
        "45TVF",
        "45TWF",
        "45TXF",
        "45TYF",
        "45TTE",
        "45TUE",
        "45TVE",
        "45TWE",
        "45TXE",
        "45TYE",
        "45UVQ",
        "45UWQ",
        "45UUP",
        "45UVP",
        "45UWP",
        "45UXP",
        "46SBJ",
        "46SCJ",
        "46SDJ",
        "46SBH",
        "46SCH",
        "46SBG",
        "46SCG",
        "46SBF",
        "46SCF",
        "46SBE",
        "46SCE",
        "46TCT",
        "46TCS",
        "46TCR",
        "46TCQ",
        "46TDQ",
        "46TEQ",
        "46TFQ",
        "46TCP",
        "46TDP",
        "46TEP",
        "46TFP",
        "46TGP",
        "46TCN",
        "46TDN",
        "46TEN",
        "46TFN",
        "46TGN",
        "46TCM",
        "46TDM",
        "46TEM",
        "46TFM",
        "46TGM",
        "46TBL",
        "46TCL",
        "46TDL",
        "46TEL",
        "46TFL",
        "46TBK",
        "46TCK",
        "46TDK",
        "46TEK",
        "45TTG",
        "46TBM",
        "47TKG"
    ],
    "香港": [
        "49QGE",
        "49QHE",
        "50QKK"
    ],
    "西藏": [
        "44RKV",
        "44RLV",
        "44RMV",
        "44RNV",
        "44RPV",
        "44RQV",
        "44RMU",
        "44RNU",
        "44RPU",
        "44RQU",
        "44RPT",
        "44RQT",
        "44SME",
        "44SNE",
        "44SPE",
        "44SQE",
        "44SLD",
        "44SMD",
        "44SND",
        "44SPD",
        "44SQD",
        "44SKC",
        "44SLC",
        "44SMC",
        "44SNC",
        "44SPC",
        "44SQC",
        "44SKB",
        "44SLB",
        "44SMB",
        "44SNB",
        "44SPB",
        "44SQB",
        "44SKA",
        "44SLA",
        "44SMA",
        "44SNA",
        "44SPA",
        "44SQA",
        "45RTQ",
        "45RUQ",
        "45RVQ",
        "45RWQ",
        "45RXQ",
        "45RYQ",
        "45RTP",
        "45RUP",
        "45RVP",
        "45RWP",
        "45RXP",
        "45RYP",
        "45RTN",
        "45RUN",
        "45RVN",
        "45RWN",
        "45RXN",
        "45RYN",
        "45RTM",
        "45RUM",
        "45RVM",
        "45RWM",
        "45RXM",
        "45RYM",
        "45RUL",
        "45RVL",
        "45RWL",
        "45RXL",
        "45RYL",
        "45SVA",
        "45SWA",
        "45SXA",
        "45SYA",
        "45STV",
        "45SUV",
        "45SVV",
        "45SWV",
        "45SXV",
        "45SYV",
        "45STU",
        "45SUU",
        "45SVU",
        "45SWU",
        "45SXU",
        "45SYU",
        "45STT",
        "45SUT",
        "45SVT",
        "45SWT",
        "45SXT",
        "45SYT",
        "45STS",
        "45SUS",
        "45SVS",
        "45SWS",
        "45SXS",
        "45SYS",
        "45STR",
        "45SUR",
        "45SVR",
        "45SWR",
        "45SXR",
        "45SYR",
        "46RBV",
        "46RCV",
        "46RDV",
        "46REV",
        "46RFV",
        "46RGV",
        "46RBU",
        "46RCU",
        "46RDU",
        "46REU",
        "46RFU",
        "46RGU",
        "46RBT",
        "46RCT",
        "46RDT",
        "46RET",
        "46RFT",
        "46RGT",
        "46RBS",
        "46RCS",
        "46RDS",
        "46RES",
        "46RFS",
        "46RGS",
        "46RBR",
        "46RCR",
        "46RDR",
        "46RER",
        "46RFR",
        "46RGR",
        "46RDQ",
        "46REQ",
        "46SBC",
        "46SBB",
        "46SCB",
        "46SDB",
        "46SEB",
        "46SFB",
        "46SBA",
        "46SCA",
        "46SDA",
        "46SEA",
        "46SFA",
        "46SGA",
        "47RKQ",
        "47RLQ",
        "47RMQ",
        "47RKP",
        "47RLP",
        "47RMP",
        "47RNP",
        "47RKN",
        "47RLN",
        "47RMN",
        "47RNN",
        "47RKM",
        "47RLM",
        "47RMM",
        "47RKL",
        "47RLL",
        "47SLS",
        "47SKR",
        "47SLR",
        "47SMR"
    ],
    "台湾省": [
        "51QTG",
        "51QUG",
        "51QTF",
        "51QUF",
        "51QTE",
        "51RTH",
        "51RUH"
    ],
    "四川省": [
        "48RTV",
        "48RUV",
        "48RVV",
        "48RWV",
        "48RXV",
        "48RYV",
        "48RTU",
        "48RUU",
        "48RVU",
        "48RWU",
        "48RXU",
        "48RYU",
        "48RTT",
        "48RUT",
        "48RVT",
        "48RWT",
        "48RXT",
        "48RTS",
        "48RUS",
        "48RVS",
        "48RWS",
        "48RXS",
        "48RTR",
        "48RUR",
        "48RVR",
        "48RWR",
        "48RXR",
        "48RTQ",
        "48RUQ",
        "48RTP",
        "48STC",
        "48SUC",
        "48SVC",
        "48STB",
        "48SUB",
        "48SVB",
        "48SWB",
        "48SXB",
        "48SYB",
        "48STA",
        "48SUA",
        "48SVA",
        "48SWA",
        "48SXA",
        "48SYA",
        "49RBQ",
        "49SBR",
        "47RMQ",
        "47RNQ",
        "47RPQ",
        "47RQQ",
        "47RMP",
        "47RNP",
        "47RPP",
        "47RQP",
        "47RMN",
        "47RNN",
        "47RPN",
        "47RQN",
        "47RNM",
        "47RPM",
        "47RQM",
        "47RPL",
        "47RQL",
        "47RQK",
        "47RQJ",
        "47RRJ",
        "47SLT",
        "47SMT",
        "47SQT",
        "47SLS",
        "47SMS",
        "47SNS",
        "47SPS",
        "47SQS",
        "47SLR",
        "47SMR",
        "47SNR",
        "47SPR",
        "47SQR"
    ],
    "陕西省": [
        "48SXG",
        "48SYG",
        "48SYF",
        "48SYE",
        "48SXD",
        "48SYD",
        "48SWC",
        "48SXC",
        "48SYC",
        "48SWB",
        "48SXB",
        "48SYB",
        "48SXA",
        "48SYA",
        "49SCD",
        "49SDD",
        "49SED",
        "49SCC",
        "49SDC",
        "49SEC",
        "49SBB",
        "49SCB",
        "49SDB",
        "49SBA",
        "49SCA",
        "49SDA",
        "49SBV",
        "49SCV",
        "49SDV",
        "49SBU",
        "49SCU",
        "49SDU",
        "49SBT",
        "49SCT",
        "49SDT",
        "49SET",
        "49SBS",
        "49SCS",
        "49SDS",
        "49SES",
        "49SBR",
        "49SCR"
    ],
    "山西省": [
        "49SDD",
        "49SED",
        "49SFD",
        "49SGD",
        "49SDC",
        "49SEC",
        "49SFC",
        "49SGC",
        "49SDB",
        "49SEB",
        "49SFB",
        "49SGB",
        "49SDA",
        "49SEA",
        "49SFA",
        "49SGA",
        "49SDV",
        "49SEV",
        "49SFV",
        "49SGV",
        "49SDU",
        "49SEU",
        "49SFU",
        "49TEE",
        "49TFE",
        "49TGE",
        "50SKJ",
        "50SKG",
        "50TKL",
        "50TKK"
    ],
    "山东省": [
        "50SNH",
        "50SPH",
        "50SLG",
        "50SMG",
        "50SNG",
        "50SPG",
        "50SQG",
        "50SLF",
        "50SMF",
        "50SNF",
        "50SPF",
        "50SQF",
        "50SLE",
        "50SME",
        "50SNE",
        "50SPE",
        "50SQE",
        "50SKD",
        "50SLD",
        "50SMD",
        "50SND",
        "50SPD",
        "50SQD",
        "51STB",
        "51SUB",
        "51SVB",
        "51STA",
        "51SUA",
        "51SVA",
        "51STV"
    ],
    "青海省": [
        "48STG",
        "48STF",
        "48SUF",
        "48STE",
        "48SUE",
        "48STD",
        "48STC",
        "45SYA",
        "45SYV",
        "45SYU",
        "45SYT",
        "46SCJ",
        "46SDJ",
        "46SEJ",
        "46SFJ",
        "46SGJ",
        "46SBH",
        "46SCH",
        "46SDH",
        "46SEH",
        "46SFH",
        "46SGH",
        "46SBG",
        "46SCG",
        "46SDG",
        "46SEG",
        "46SFG",
        "46SGG",
        "46SBF",
        "46SCF",
        "46SDF",
        "46SEF",
        "46SFF",
        "46SGF",
        "46SBE",
        "46SCE",
        "46SDE",
        "46SEE",
        "46SFE",
        "46SGE",
        "46SBD",
        "46SCD",
        "46SDD",
        "46SED",
        "46SFD",
        "46SGD",
        "46SBC",
        "46SCC",
        "46SDC",
        "46SEC",
        "46SFC",
        "46SGC",
        "46SBB",
        "46SCB",
        "46SDB",
        "46SEB",
        "46SFB",
        "46SGB",
        "46SEA",
        "46SFA",
        "46SGA",
        "47RKQ",
        "47SLD",
        "47SMD",
        "47SND",
        "47SKC",
        "47SLC",
        "47SMC",
        "47SNC",
        "47SPC",
        "47SKB",
        "47SLB",
        "47SMB",
        "47SNB",
        "47SPB",
        "47SQB",
        "47SKA",
        "47SLA",
        "47SMA",
        "47SNA",
        "47SPA",
        "47SQA",
        "47SKV",
        "47SLV",
        "47SMV",
        "47SNV",
        "47SPV",
        "47SQV",
        "47SKU",
        "47SLU",
        "47SMU",
        "47SNU",
        "47SPU",
        "47SQU",
        "47SKT",
        "47SLT",
        "47SMT",
        "47SNT",
        "47SPT",
        "47SQT",
        "47SKS",
        "47SLS",
        "47SMS",
        "47SNS",
        "47SPS",
        "47SQS",
        "47SKR",
        "47SLR",
        "47SPR"
    ],
    "宁夏": [
        "48SWJ",
        "48SXJ",
        "48SWH",
        "48SXH",
        "48SYH",
        "48SVG",
        "48SWG",
        "48SXG",
        "48SYG",
        "48SVF",
        "48SWF",
        "48SXF",
        "48SWE",
        "48SXE"
    ],
    "内蒙古": [
        "48STJ",
        "48SUJ",
        "48SVJ",
        "48SWJ",
        "48SXJ",
        "48SYJ",
        "48SUH",
        "48SVH",
        "48SWH",
        "48SXH",
        "48SYH",
        "48SUG",
        "48SVG",
        "48SWG",
        "48SYG",
        "48TXN",
        "48TYN",
        "48TUM",
        "48TVM",
        "48TWM",
        "48TXM",
        "48TYM",
        "48TTL",
        "48TUL",
        "48TVL",
        "48TWL",
        "48TXL",
        "48TYL",
        "48TTK",
        "48TUK",
        "48TVK",
        "48TWK",
        "48TXK",
        "48TYK",
        "49SBD",
        "49SCD",
        "49SDD",
        "49SED",
        "49SBC",
        "49SCC",
        "49SBB",
        "49SCB",
        "49TEK",
        "49TFK",
        "49TGK",
        "49TEJ",
        "49TFJ",
        "49TGJ",
        "49TCH",
        "49TDH",
        "49TEH",
        "49TFH",
        "49TGH",
        "49TCG",
        "49TDG",
        "49TEG",
        "49TFG",
        "49TGG",
        "49TBF",
        "49TCF",
        "49TDF",
        "49TEF",
        "49TFF",
        "49TGF",
        "49TBE",
        "49TCE",
        "49TDE",
        "49TEE",
        "49TFE",
        "49TGE",
        "50TMT",
        "50TNT",
        "50TPT",
        "50TQT",
        "50TMS",
        "50TNS",
        "50TPS",
        "50TQS",
        "50TLR",
        "50TMR",
        "50TNR",
        "50TPR",
        "50TQR",
        "50TLQ",
        "50TMQ",
        "50TNQ",
        "50TPQ",
        "50TQQ",
        "50TLP",
        "50TMP",
        "50TNP",
        "50TPP",
        "50TQP",
        "50TLN",
        "50TMN",
        "50TNN",
        "50TPN",
        "50TQN",
        "50TLM",
        "50TMM",
        "50TNM",
        "50TPM",
        "50TQM",
        "50TKL",
        "50TPL",
        "50TQL",
        "50TKK",
        "50UQC",
        "50UPB",
        "50UQB",
        "50UMA",
        "50UNA",
        "50UPA",
        "50UQA",
        "50UMV",
        "50UNV",
        "50UPV",
        "50UQV",
        "50ULU",
        "50UMU",
        "50UNU",
        "50UPU",
        "50UQU",
        "51TUN",
        "51TVN",
        "51TWN",
        "51TUM",
        "51TVM",
        "51TWM",
        "51TUL",
        "51TVL",
        "51TUK",
        "51TVK",
        "51TWK",
        "51TUJ",
        "51TVJ",
        "51TWJ",
        "51TUH",
        "51TVH",
        "51TWH",
        "51TUG",
        "51UUV",
        "51UVV",
        "51UUU",
        "51UVU",
        "51UUT",
        "51UVT",
        "51UXT",
        "51UUS",
        "51UVS",
        "51UWS",
        "51UXS",
        "51UYS",
        "51UUR",
        "51UVR",
        "51UWR",
        "51UXR",
        "51UUQ",
        "51UVQ",
        "51UWQ",
        "51UXQ",
        "51UUP",
        "51UVP",
        "51UWP",
        "51UXP",
        "47SND",
        "47SPD",
        "47SQD",
        "47SPC",
        "47SQC",
        "47TLH",
        "47TMH",
        "47TNH",
        "47TPH",
        "47TQH",
        "47TLG",
        "47TMG",
        "47TNG",
        "47TPG",
        "47TQG",
        "47TLF",
        "47TMF",
        "47TNF",
        "47TPF",
        "47TQF",
        "47TNE",
        "47TPE",
        "47TQE",
        "48TTM",
        "49TBG",
        "50TKM",
        "51TTG"
    ],
    "辽宁省": [
        "50TPM",
        "50TQM",
        "50TPL",
        "50TQL",
        "50TPK",
        "50TQK",
        "51SUD",
        "51SVD",
        "51SWD",
        "51SUC",
        "51TWJ",
        "51TUH",
        "51TVH",
        "51TWH",
        "51TXH",
        "51TUG",
        "51TVG",
        "51TWG",
        "51TXG",
        "51TYG",
        "51TTF",
        "51TUF",
        "51TVF",
        "51TWF",
        "51TXF",
        "51TYF",
        "51TTE",
        "51TUE",
        "51TVE",
        "51TWE",
        "51TXE",
        "51TYE",
        "51TTG"
    ],
    "江西省": [
        "49RGN",
        "49RGM",
        "49RGL",
        "49RGK",
        "49RGJ",
        "49RHJ",
        "50RLU",
        "50RMU",
        "50RNU",
        "50RKT",
        "50RLT",
        "50RMT",
        "50RNT",
        "50RPT",
        "50RKS",
        "50RLS",
        "50RMS",
        "50RNS",
        "50RPS",
        "50RKR",
        "50RLR",
        "50RMR",
        "50RNR",
        "50RPR",
        "50RKQ",
        "50RLQ",
        "50RMQ",
        "50RNQ",
        "50RKP",
        "50RLP",
        "50RMP",
        "50RKN",
        "50RLN"
    ],
    "吉林省": [
        "51TVM",
        "51TWM",
        "51TUL",
        "51TVL",
        "51TWL",
        "51TXL",
        "51TYL",
        "51TVK",
        "51TWK",
        "51TXK",
        "51TYK",
        "51TVJ",
        "51TWJ",
        "51TXJ",
        "51TYJ",
        "51TWH",
        "51TXH",
        "51TYH",
        "51TXG",
        "51TYG",
        "51TYF",
        "52TCR",
        "52TCQ",
        "52TDQ",
        "52TCP",
        "52TDP",
        "52TEP",
        "52TFP",
        "52TCN",
        "52TDN",
        "52TEN",
        "52TFN",
        "52TCM",
        "52TDM",
        "52TEM",
        "52TFM",
        "52TBL",
        "52TCL",
        "52TDL",
        "52TBM"
    ],
    "湖南省": [
        "49RDP",
        "49REP",
        "49RGP",
        "49RCN",
        "49RDN",
        "49REN",
        "49RFN",
        "49RGN",
        "49RCM",
        "49RDM",
        "49REM",
        "49RFM",
        "49RGM",
        "49RBL",
        "49RCL",
        "49RDL",
        "49REL",
        "49RFL",
        "49RGL",
        "49RBK",
        "49RCK",
        "49RDK",
        "49REK",
        "49RFK",
        "49RGK",
        "49RCJ",
        "49RDJ",
        "49REJ",
        "49RFJ",
        "49RGJ",
        "49RHJ",
        "49RDH",
        "49REH",
        "49RFH",
        "49RGH",
        "50RKT",
        "50RKS",
        "50RKQ",
        "50RKP"
    ],
    "湖北省": [
        "49RCQ",
        "49RDQ",
        "49REQ",
        "49RFQ",
        "49RGQ",
        "49RBP",
        "49RCP",
        "49RDP",
        "49REP",
        "49RFP",
        "49RGP",
        "49RBN",
        "49RCN",
        "49RDN",
        "49REN",
        "49RFN",
        "49RGN",
        "49SCS",
        "49SDS",
        "49SES",
        "49SCR",
        "49SDR",
        "49SER",
        "49SFR",
        "49SGR",
        "50RKV",
        "50RLV",
        "50RMV",
        "50RKU",
        "50RLU",
        "50RMU",
        "50RKT",
        "50RLT",
        "50RMT"
    ],
    "黑龙江": [
        "51TVN",
        "51TWN",
        "51TXN",
        "51TYN",
        "51TVM",
        "51TWM",
        "51TXM",
        "51TYM",
        "51TWL",
        "51TXL",
        "51TYL",
        "51UUV",
        "51UVV",
        "51UWV",
        "51UUU",
        "51UVU",
        "51UWU",
        "51UXU",
        "51UYU",
        "51UVT",
        "51UWT",
        "51UXT",
        "51UYT",
        "51UVS",
        "51UWS",
        "51UXS",
        "51UYS",
        "51UXR",
        "51UYR",
        "51UXQ",
        "51UYQ",
        "51UWP",
        "51UXP",
        "51UYP",
        "52TCT",
        "52TDT",
        "52TET",
        "52TFT",
        "52TGT",
        "52TCS",
        "52TDS",
        "52TES",
        "52TFS",
        "52TGS",
        "52TCR",
        "52TDR",
        "52TER",
        "52TFR",
        "52TGR",
        "52TCQ",
        "52TDQ",
        "52TEQ",
        "52TFQ",
        "52TGQ",
        "52TCP",
        "52TDP",
        "52TEP",
        "52TFP",
        "52UCD",
        "52UCC",
        "52UCB",
        "52UCA",
        "52UDA",
        "52UCV",
        "52UDV",
        "52UEV",
        "52UFV",
        "52UCU",
        "52UDU",
        "52UEU",
        "52UFU",
        "53TLN",
        "53TMN",
        "53TLM",
        "53TMM",
        "53TLL",
        "53TML",
        "53TLK",
        "53ULP",
        "53UMP",
        "53UNP"
    ],
    "河南省": [
        "49SGA",
        "49SEV",
        "49SFV",
        "49SGV",
        "49SDU",
        "49SEU",
        "49SFU",
        "49SGU",
        "49SDT",
        "49SET",
        "49SFT",
        "49SGT",
        "49SDS",
        "49SES",
        "49SFS",
        "49SGS",
        "49SER",
        "49SFR",
        "49SGR",
        "50RKV",
        "50RLV",
        "50SKF",
        "50SLF",
        "50SKE",
        "50SLE",
        "50SME",
        "50SKD",
        "50SLD",
        "50SMD",
        "50SKC",
        "50SLC",
        "50SMC",
        "50SKB",
        "50SLB",
        "50SKA",
        "50SLA"
    ],
    "北京市": [
        "50SLJ",
        "50SMJ",
        "50TML",
        "50TNL",
        "50TLK",
        "50TMK",
        "50TNK"
    ],
    "天津市": [
        "50SMJ",
        "50SNJ",
        "50SMH",
        "50SNH",
        "50TNK"
    ],
    "海南省": [
        "49QCC",
        "49QDC",
        "49QBB",
        "49QCB",
        "49QDB",
        "49QEB",
        "49QBA",
        "49QCA",
        "49QDA"
    ],
    "贵州省": [
        "48RYT",
        "48RWS",
        "48RXS",
        "48RYS",
        "48RUR",
        "48RVR",
        "48RWR",
        "48RXR",
        "48RYR",
        "48RUQ",
        "48RVQ",
        "48RWQ",
        "48RXQ",
        "48RYQ",
        "48RVP",
        "48RWP",
        "48RXP",
        "48RYP",
        "48RZP",
        "48RVN",
        "48RWN",
        "48RXN",
        "48RYN",
        "48RZN",
        "49RBN",
        "49RBM",
        "49RCM",
        "49RBL",
        "49RCL",
        "49RBK",
        "49RCK",
        "49RBJ",
        "49RCJ",
        "49RBH"
    ],
    "广西省": [
        "48QWM",
        "48QXM",
        "48QYM",
        "48QZM",
        "48QWL",
        "48QXL",
        "48QYL",
        "48QZL",
        "48QXK",
        "48QYK",
        "48QZK",
        "48QYJ",
        "48QZJ",
        "48RXP",
        "48RYP",
        "48RVN",
        "48RWN",
        "48RXN",
        "48RYN",
        "48RZN",
        "49QBG",
        "49QCG",
        "49QDG",
        "49QEG",
        "49QBF",
        "49QCF",
        "49QDF",
        "49QEF",
        "49QBE",
        "49QCE",
        "49QDE",
        "49QBD",
        "49QCD",
        "49RDK",
        "49REK",
        "49RBJ",
        "49RCJ",
        "49RDJ",
        "49REJ",
        "49RBH",
        "49RCH",
        "49RDH",
        "49REH",
        "49RFH"
    ],
    "甘肃省": [
        "48STJ",
        "48SUJ",
        "48SVJ",
        "48STH",
        "48SUH",
        "48SVH",
        "48STG",
        "48SUG",
        "48SVG",
        "48SXG",
        "48SYG",
        "48STF",
        "48SUF",
        "48SVF",
        "48SWF",
        "48SXF",
        "48SYF",
        "48STE",
        "48SUE",
        "48SVE",
        "48SWE",
        "48SXE",
        "48SYE",
        "48STD",
        "48SUD",
        "48SVD",
        "48SWD",
        "48SXD",
        "48SYD",
        "48STC",
        "48SUC",
        "48SVC",
        "48SWC",
        "48SXC",
        "48STB",
        "48SVB",
        "48SWB",
        "49SBA",
        "49SBV",
        "46SDJ",
        "46SEJ",
        "46SFJ",
        "46SGJ",
        "46SGH",
        "46TFM",
        "46TGM",
        "46TEL",
        "46TFL",
        "46TGL",
        "46TDK",
        "46TEK",
        "46TFK",
        "46TGK",
        "47SKD",
        "47SLD",
        "47SMD",
        "47SND",
        "47SPD",
        "47SQD",
        "47SKC",
        "47SLC",
        "47SMC",
        "47SNC",
        "47SPC",
        "47SQC",
        "47SPB",
        "47SQB",
        "47SPU",
        "47SQU",
        "47SPT",
        "47SQT",
        "47SQS",
        "47TLH",
        "47TLG",
        "47TMG",
        "47TKF",
        "47TLF",
        "47TMF",
        "47TNF",
        "47TPF",
        "47TKE",
        "47TLE",
        "47TME",
        "47TNE",
        "47TPE",
        "47TKG"
    ],
    "福建省": [
        "50QMM",
        "50QNM",
        "50RPS",
        "50RMR",
        "50RNR",
        "50RPR",
        "50RQR",
        "50RMQ",
        "50RNQ",
        "50RPQ",
        "50RQQ",
        "50RLP",
        "50RMP",
        "50RNP",
        "50RPP",
        "50RQP",
        "50RLN",
        "50RMN",
        "50RNN",
        "50RPN",
        "50RQN",
        "51RTL",
        "51RTK"
    ],
    "澳门": [
        "49QGE"
    ],
    "安徽省": [
        "50RLV",
        "50RMV",
        "50RNV",
        "50RPV",
        "50RQV",
        "50RLU",
        "50RMU",
        "50RNU",
        "50RPU",
        "50RQU",
        "50RMT",
        "50RNT",
        "50RPT",
        "50SMD",
        "50SLC",
        "50SMC",
        "50SNC",
        "50SPC",
        "50SLB",
        "50SMB",
        "50SNB",
        "50SPB",
        "50SQB",
        "50SLA",
        "50SMA",
        "50SNA",
        "50SPA",
        "50SQA"
    ],
    "上海市": [
        "51RTQ",
        "51RUQ",
        "51RVQ",
        "51RUP"
    ],
    "重庆市": [
        "48RYV",
        "48RWU",
        "48RXU",
        "48RYU",
        "48RWT",
        "48RXT",
        "48RYT",
        "48RWS",
        "48RXS",
        "48RYS",
        "49RBQ",
        "49RCQ",
        "49RDQ",
        "49RBP",
        "49RCP",
        "49RBN",
        "49RCN",
        "49RBM",
        "49RCM",
        "49SBR"
    ],
    "江苏省": [
        "50RPV",
        "50RQV",
        "50SMD",
        "50SND",
        "50SPD",
        "50SQD",
        "50SMC",
        "50SNC",
        "50SPC",
        "50SQC",
        "50SNB",
        "50SPB",
        "50SQB",
        "50SPA",
        "50SQA",
        "51RTQ",
        "51RUQ",
        "51STU",
        "51STT",
        "51STS",
        "51SUS",
        "51STR",
        "51SUR"
    ],
    "广东省": [
        "49QEG",
        "49QFG",
        "49QGG",
        "49QHG",
        "49QDF",
        "49QEF",
        "49QFF",
        "49QGF",
        "49QHF",
        "49QCE",
        "49QDE",
        "49QEE",
        "49QFE",
        "49QGE",
        "49QHE",
        "49QCD",
        "49QDD",
        "49QED",
        "49QCC",
        "49QDC",
        "49RFJ",
        "49RGJ",
        "49RHJ",
        "49REH",
        "49RFH",
        "49RGH",
        "49RHH",
        "50QKM",
        "50QLM",
        "50QMM",
        "50QNM",
        "50QKL",
        "50QLL",
        "50QML",
        "50QKK",
        "50RKP",
        "50RKN",
        "50RLN",
        "50RMN"
    ],
    "河北省": [
        "49SGD",
        "49SGC",
        "49SGB",
        "49SGA",
        "49TGG",
        "49TGF",
        "49TGE",
        "50SKJ",
        "50SLJ",
        "50SMJ",
        "50SNJ",
        "50SPJ",
        "50SQJ",
        "50SKH",
        "50SLH",
        "50SMH",
        "50SNH",
        "50SKG",
        "50SLG",
        "50SMG",
        "50SNG",
        "50SKF",
        "50SLF",
        "50SLE",
        "50TNN",
        "50TLM",
        "50TMM",
        "50TNM",
        "50TPM",
        "50TKL",
        "50TLL",
        "50TML",
        "50TNL",
        "50TPL",
        "50TKK",
        "50TLK",
        "50TMK",
        "50TNK",
        "50TPK",
        "50TQK",
        "50TKM"
    ],
    "东四盟": [
        "50TLU",
        "50TMU",
        "50TNU",
        "50TPU",
        "50TQU",
        "50TMT",
        "50TNT",
        "50TPT",
        "50TQT",
        "50TQS",
        "50TPR",
        "50TQR",
        "50TPQ",
        "50TQQ",
        "50TMP",
        "50TNP",
        "50TPP",
        "50TQP",
        "50TMN",
        "50TNN",
        "50TPN",
        "50TQN",
        "50TMM",
        "50TNM",
        "50TPM",
        "50TQM",
        "50TPL",
        "50TQL",
        "50UQC",
        "50UPB",
        "50UQB",
        "50UMA",
        "50UNA",
        "50UPA",
        "50UQA",
        "50UMV",
        "50UNV",
        "50UPV",
        "50UQV",
        "50ULU",
        "50UMU",
        "50UNU",
        "50UPU",
        "50UQU",
        "51TTP",
        "51TUP",
        "51TVP",
        "51TWP",
        "51TTN",
        "51TUN",
        "51TVN",
        "51TWN",
        "51TTM",
        "51TUM",
        "51TVM",
        "51TWM",
        "51TTL",
        "51TUL",
        "51TVL",
        "51TTK",
        "51TUK",
        "51TVK",
        "51TWK",
        "51TTJ",
        "51TUJ",
        "51TVJ",
        "51TWJ",
        "51TTH",
        "51TUH",
        "51TVH",
        "51TWH",
        "51TTG",
        "51TUG",
        "51UUV",
        "51UVV",
        "51UTU",
        "51UUU",
        "51UVU",
        "51UTT",
        "51UUT",
        "51UVT",
        "51UXT",
        "51UTS",
        "51UUS",
        "51UVS",
        "51UWS",
        "51UXS",
        "51UYS",
        "51UTR",
        "51UUR",
        "51UVR",
        "51UWR",
        "51UXR",
        "51UTQ",
        "51UUQ",
        "51UVQ",
        "51UWQ",
        "51UXQ",
        "51UTP",
        "51UUP",
        "51UVP",
        "51UWP",
        "51UXP",
        "52UBB"
    ]
}


account_infos = {
		"请选择ESA账号":"请选择ESA账号",
		"fyy001": "show1234",
		"fyy_01": "show1234",
		"fyy_02": "show1234",
		"fyy_03": "show1234",
		"fyy_04": "show1234",
		"wyq01": "show970213",
		"wyq02": "show970213",
		"wyq03": "show970213",
		"wyq04": "show970213",
		"wyq05": "show970213",
		"wyq06": "show970213",
		"wyq07": "show970213",
		"hxx2021": "hxx2021123",
		"hxx2022": "hxx2022123",
		"hxx20221": "hxx2022123",
		"hxx20222": "hxx20222123",
	}


# 清临时数据
def delete_incomplete(args):
	[tiles, start_date, end_date, save_folder] = args
	start_date = datetime.datetime.strptime(start_date,"%Y-%m-%d")
	end_date = datetime.datetime.strptime(end_date,"%Y-%m-%d")
	temp_date = start_date
	dates = []
	while temp_date < (end_date+datetime.timedelta(days=1)):
		dates.append(temp_date.strftime("%Y%m%d"))
		temp_date = temp_date + datetime.timedelta(days=1)
	datestr = "|".join(dates)
	tilestr = "|".join(tiles)
	name_re = f"^S2.*_({datestr})T.*_T({tilestr})_.*\.zip\.incomplete$"
	for name in os.listdir(save_folder):
		if re.match(name_re,name):
			os.remove(os.path.join(save_folder, name))
	return


# check 172 service sentinel2 1c zip file
def check_sentinel2_in172(args):
    hostname,port,username,password,tiles,start_date,end_date,folder=args
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    # client.connect(hostname="192.168.2.172",port=22,username="root",password="DELL123dell")
    client.connect(hostname=hostname,port=port,username=username,password=password)
    sftp: paramiko.SFTPClient = client.open_sftp() 
   
    dates = []
    start_date = datetime.datetime.strptime(start_date,"%Y-%m-%d")
    end_date = datetime.datetime.strptime(end_date,"%Y-%m-%d")
    while start_date<=end_date:
        dates.append(start_date.strftime("%Y%m%d"))
        start_date = start_date+datetime.timedelta(days=1)

    products = {}
    for dir_name in dates:
        date_dir = str(pathlib.PurePosixPath(folder,dir_name))
        try:
            sftp.stat(date_dir)
        except:
            sftp.mkdir(date_dir)
        for file_name in sftp.listdir(date_dir):
            if re.match(f"^S2[AB]_MSIL1C_{dir_name}T.*\.zip$",file_name):
                tile = file_name.split("_")[5][1:]
                if tile in tiles:
                    remote_path=str(pathlib.PurePosixPath(date_dir,file_name))
                    file_size = round(sftp.stat(remote_path).st_size/(1024*1024),2)
                    products.update({file_name.replace(".zip",".SAFE"): file_size})

    sftp.close()
    client.close()           
    return products


# download sentinel2 data
def sentinel2_downloader(args):

    [username,password,tiles,start_date,end_date,max_cloud,exists,folder,n_concurrent_dl,sleep]=args

    api = SentinelAPI(
        username,
        password,
        api_url='https://scihub.copernicus.eu/dhus/',
        show_progressbars=True,
        timeout=60
    )
    zip_paths = []
    for tile in tiles:
        # 查询
        query_kwargs = {
            'platformname': 'Sentinel-2',
            'producttype': 'S2MSI1C',
            'date': (
                datetime.datetime.strptime(start_date,"%Y-%m-%d"), 
                datetime.datetime.strptime(f"{end_date} 23:59:59","%Y-%m-%d %H:%M:%S")
            ),
            'cloudcoverpercentage': (0, max_cloud),
            'tileid': tile,
            'raw': f'tileid:{tile} OR filename:*_T{tile}_*'
        }
        products=api.query(**query_kwargs)
        # 下载
        for id in products:
            filename = products[id]['filename']
           
            date_name = products[id]['datatakesensingstart'].strftime("%Y%m%d")
            data_folder = os.path.join(folder, date_name)
            if not os.path.exists(data_folder):
                os.makedirs(data_folder)
            esa_size = float(products[id]['size'].split(' ')[0])
            # differ = abs(exists[filename]-esa_size)
            is_exists = filename in list(exists.keys())
            if not (is_exists and abs(exists[filename]-esa_size)<=0.04):
                try:
                    success_list = api.download_all(
                        [id],
                        data_folder,
                        checksum=True,
                        n_concurrent_dl=n_concurrent_dl
                    )
                    for success in success_list:
                        success_dict = dict(success)
                        for key in success_dict.keys():
                            try:
                                zip_paths.append(success_dict[key]['path'])
                            except:
                                pass
                    time.sleep(sleep)
                except:
                    pass
                
    return zip_paths


# link zip file
def zip_file_link(args):
    hostname,port,username,password,zip_paths,province_dir=args
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    client.connect(hostname=hostname,port=port,username=username,password=password)
    sftp: paramiko.SFTPClient = client.open_sftp() 
    zip_dir = r"/home/万裕青/遥感数据/Sentinel2L1cZip"
    for zip_path in zip_paths:
        date_name = os.path.basename(os.path.dirname(zip_path))
        yearmonth = date_name[:6]
        zip_name = os.path.basename(zip_path)
        source_path = str(pathlib.PurePosixPath(zip_dir,date_name,zip_name))
        yearmonth_dir = str(pathlib.PurePosixPath(province_dir,yearmonth))
        try:
            sftp.stat(yearmonth_dir)
        except:
            sftp.mkdir(yearmonth_dir)
        cmd = f"ln {source_path} {yearmonth_dir}"
        client.exec_command(cmd)
    sftp.close()
    client.close()
    return


# ui
class my_ui:

    width, height = 800, 880
    line_height = 50
    provinces = list(china_tiles.keys())

    def __init__(self):
        # 定义窗口
        self.get_window()
        self.config_path = tk.StringVar()
        self.link_folder = tk.StringVar()
        self.zip_folder = tk.StringVar()
        self.link_folder.set(r"Z:\ProvinceZip")
        self.zip_folder.set(r"Z:\Sentinel2L1cZip")
        self.tiles_str = tk.StringVar()
        line_iter = iter(range(50))
        self.sentinel_frame(next(line_iter))
        self.province_frame(next(line_iter))
        self.period_frame(next(line_iter))
        self.thread_frame(next(line_iter))
        self.cloud_frame(next(line_iter))
        self.sleep_frame(next(line_iter))
        self.acount_frame(next(line_iter))
        self.zip_folder_frame(next(line_iter))
        self.link_folder_frame(next(line_iter))
        # self.send_data_frame(next(line_iter))
        self.start_button_frame(next(line_iter))
        self.progressbar_frame(next(line_iter))
        self.print_running_frame(next(line_iter))
        self.window.mainloop()

    def get_window(self):
        self.window = tk.Tk()
        self.window.title('Sentinel-2 By ESA')
        screenwidth = self.window.winfo_screenwidth() # 屏幕宽度
        screenheight = self.window.winfo_screenheight() # 屏幕高度
        x = int((screenwidth - self.width) / 2)
        y = int((screenheight - self.height) / 2)
        locat = f"{self.width}x{self.height}+{x}+{y}"
        self.window.geometry(locat) # 大小以及位置
        self.window.resizable(0,0) 
        return

    def sentinel_frame(self, row):
        frame=tkinter.ttk.Frame(self.window,width=self.width)
        frame.place(x=0,y=self.line_height*row)
        column_iter = iter(range(10))

        tk.Label(
            frame,text="图幅列表",font=('宋体','14','bold'),height=3,
        ).grid(column=next(column_iter),row=0,sticky=tk.W+tk.E)

        frame2 = tkinter.ttk.Frame(frame)
        frame2.grid(column=1,row=0,sticky=tk.W+tk.E)

        self.tilestr_entry=tk.Entry(
            frame2,
            width=63,
            background = 'white',
            borderwidth = 3,
            relief = 'sunken',
            insertwidth = 3,
            font = ('Helvetica', '14', 'bold'),
            textvariable=self.tiles_str,
            selectforeground = 'red',
            selectbackground = 'blue',
            selectborderwidth = 3,
            show=None)
        self.tilestr_entry.pack(side=tk.TOP,fill=tk.NONE) 

        scroll = tk.Scrollbar(
            frame2,
            orient=tk.HORIZONTAL,
            cursor="arrow",
            command=self.tilestr_entry.xview,
            # width=85
        )
        scroll.pack(side=tk.BOTTOM,fill=tk.X, padx=0)
        self.tilestr_entry.config(xscrollcommand=scroll.set)

        return

    def province_frame(self, row):
        frame=tkinter.ttk.Frame(self.window)
        frame.place(x=0,y=self.line_height*row)
        column_iter = iter(range(10))
        tk.Label(
            frame,text="选择省份",font=('宋体','14','bold'),height=3,
        ).grid(column=next(column_iter),row=0,sticky=tk.W+tk.E)
        self.province_combobox=tkinter.ttk.Combobox(
            frame,
            # width=6,
            height=len(self.provinces),
            state='readonly',
            cursor="arrow",
            background = 'white',
            textvariable="请选择省份（非必须）",
            font = ('', '12', ''),
            values=self.provinces,
            show=None
        )
        self.province_combobox.grid(column=next(column_iter),row=0,sticky='we')
        self.province_combobox.current(0)

        self.province_combobox.bind(
            '<<ComboboxSelected>>', 
            lambda event: (
                self.tiles_str.set("-".join(china_tiles[self.province_combobox.get()])),
                self.scrolled_text.delete(0.0, tkinter.END),
                self.window.update(),
                self.update_info("-".join(china_tiles[self.province_combobox.get()]))	
            )
        )
        return

    def period_frame(self,row):
        frame=tkinter.ttk.Frame(self.window)
        frame.place(x=0,y=self.line_height*row)
        column_iter = iter(range(10))

        tk.Label(
            frame,text="开始时间",font=('宋体','14','bold'),height=3,
        ).grid(column=next(column_iter),row=0,sticky=tk.W+tk.E)
        
        self.start_date(frame,column_iter)

        tk.Label(
            frame,text="结束时间",font=('宋体','14','bold'),height=3,
        ).grid(column=next(column_iter),row=0,sticky='we')

        self.end_date(frame, column_iter)
        return

    def start_date(self, frame, column_iter):
        self.start_year=tkinter.ttk.Combobox(
            frame,
            width=4,
            state='readonly',
            cursor="arrow",
            background = 'white',
            textvariable="",  # 必须为空
            font = ('', '12', ''),
            values=tuple(range(datetime.datetime.now().year,2016,-1)),
            show=None
        )
        self.start_year.current(0)
        self.start_year.grid(column=next(column_iter),row=0,sticky='we')
        self.start_month=tkinter.ttk.Combobox(
            frame,
            width=2,
            height=12,
            state='readonly',
            cursor="arrow",
            background = 'white',
            textvariable="",
            font = ('', '12', ''),
            values=tuple(range(1,13)),
            show=None
        )
        self.start_month.current(0)
        self.start_month.grid(column=next(column_iter),row=0,sticky='we')

        self.start_month.bind(
            '<<ComboboxSelected>>', 
            lambda event: (
                self.start_day.config(
                    {"values":tuple(
                            range(
                                1,
                                calendar.monthrange(
                                    int(self.start_year.get()), 
                                    int(self.start_month.get())
                                )[1]+1
                            )
                        )
                    }
                ),
                self.start_day.config(
                    {
                        "values": tuple(
                            range(
                                1,
                                calendar.monthrange(
                                    int(self.start_year.get()), 
                                    int(self.start_month.get())
                                )[1]+1
                            )
                        )
                    }
                ),
                self.start_day.config(
                    {
                        "height": calendar.monthrange(
                                    int(self.start_year.get()), 
                                    int(self.start_month.get())
                                )[1]		
                    }
                ),
                self.start_day.current(0)
            )
        )
        self.start_year.bind(
            '<<ComboboxSelected>>', 
            lambda event: (
                self.start_day.config(
                    {"values":tuple(
                            range(
                                1,
                                calendar.monthrange(
                                    int(self.start_year.get()), 
                                    int(self.start_month.get())
                                )[1]+1
                            )
                        )
                    }
                ),
                self.start_day.config(
                    {
                        "values": tuple(
                            range(
                                1,
                                calendar.monthrange(
                                    int(self.start_year.get()), 
                                    int(self.start_month.get())
                                )[1]+1
                            )
                        )
                    }
                ),
                self.start_day.config(
                    {
                        "height": calendar.monthrange(
                                    int(self.start_year.get()), 
                                    int(self.start_month.get())
                                )[1]		
                    }
                ),
                self.start_day.current(0)
            )
        )

        self.start_day=tkinter.ttk.Combobox(
            frame,
            width=2,
            # height=day_count,
            state='readonly',
            cursor="arrow",
            background = 'white',
            textvariable="",
            font = ('', '12', ''),
            # values=days,
            show=None
        )
        self.start_day.grid(column=next(column_iter),row=0,sticky='we')
        return

    def end_date(self,frame, column_iter):
        self.end_year=tkinter.ttk.Combobox(
            frame,
            width=4,
            state='readonly',
            cursor="arrow",
            background = 'white',
            textvariable="",
            font = ('', '12', ''),
            values=tuple(range(datetime.datetime.now().year,2016,-1)),
            show=None
        )
        self.end_year.current(0)
        self.end_year.grid(column=next(column_iter),row=0,sticky='we')
        self.end_month=tkinter.ttk.Combobox(
            frame,
            width=2,
            height=12,
            state='readonly',
            cursor="arrow",
            background = 'white',
            textvariable="",
            font = ('', '12', ''),
            values=tuple(range(1,13)),
            show=None
        )
        self.end_month.current(0)
        self.end_month.grid(column=next(column_iter),row=0,sticky='we')

        self.end_month.bind(
            '<<ComboboxSelected>>', 
            lambda event: (
                self.end_day.config(
                    {"values":tuple(
                            range(
                                1,
                                calendar.monthrange(
                                    int(self.end_year.get()), 
                                    int(self.end_month.get())
                                )[1]+1
                            )
                        )
                    }
                ),
                self.end_day.config(
                    {
                        "values": tuple(
                            range(
                                1,
                                calendar.monthrange(
                                    int(self.end_year.get()), 
                                    int(self.end_month.get())
                                )[1]+1
                            )
                        )
                    }
                ),
                self.end_day.config(
                    {
                        "height": calendar.monthrange(
                                    int(self.end_year.get()), 
                                    int(self.end_month.get())
                                )[1]
                    }
                ),
                self.end_day.current(calendar.monthrange(
                                    int(self.end_year.get()), 
                                    int(self.end_month.get())
                                )[1]-1
                )
            )
        )
        self.end_year.bind(
            '<<ComboboxSelected>>', 
            lambda event: (
                self.end_day.config(
                    {"values":tuple(
                            range(
                                1,
                                calendar.monthrange(
                                    int(self.end_year.get()), 
                                    int(self.end_month.get())
                                )[1]+1
                            )
                        )
                    }
                ),
                self.end_day.config(
                    {
                        "values": tuple(
                            range(
                                1,
                                calendar.monthrange(
                                    int(self.end_year.get()), 
                                    int(self.end_month.get())
                                )[1]+1
                            )
                        )
                    }
                ),
                self.end_day.config(
                    {
                        "height": calendar.monthrange(
                                    int(self.end_year.get()), 
                                    int(self.end_month.get())
                                )[1]
                    }
                ),
                self.end_day.current(calendar.monthrange(
                                    int(self.end_year.get()), 
                                    int(self.end_month.get())
                                )[1]-1
                )
            )
        )

        self.end_day=tkinter.ttk.Combobox(
            frame,
            width=2,
            # height=day_count,
            state='readonly',
            cursor="arrow",
            background = 'white',
            textvariable="",
            font = ('', '12', ''),
            # values=days,
            show=None
        )
        self.end_day.grid(column=next(column_iter),row=0,sticky='we')
        return

    def thread_frame(self,row):
        frame=tkinter.ttk.Frame(self.window)
        frame.place(x=0,y=self.line_height*row)
        tk.Label(
            frame,text=f"线程数量",font=('宋体','14','bold'),height=3,
        ).grid(column=0,row=0,sticky='we')
        max_thread = tk.IntVar()
        max_thread.set(1)
        self.thread_scale=tk.Scale(
            frame, 
            # label="MaxCloud",    # 标签
            variable=max_thread, 	# 值
            from_=1,    #  最小值， 记住是from_， from是关键字
            to=4,       #  最大值
            resolution=1,  # 步进值
            show=True,   # 是否在上面显示值
            orient=tk.HORIZONTAL,  # 水平显示
            length=680,  # 滑块长度
            # command=lambda value, key=k:self.get_value(value, key)
        )
        self.thread_scale.grid(column=1,row=0,sticky='we')
        return

    def cloud_frame(self, row):
        frame=tkinter.ttk.Frame(self.window)
        frame.place(x=0,y=self.line_height*row)
        tk.Label(
            frame,text=f"最大云量",font=('宋体','14','bold'),height=3,
        ).grid(column=0,row=0,sticky='we')
        max_clound = tk.IntVar()
        max_clound.set(100)
        self.maxcloud_scale=tk.Scale(
            frame, 
            # label="MaxCloud",    # 标签
            variable=max_clound, 	# 值
            from_=0,    #  最小值， 记住是from_， from是关键字
            to=100,       #  最大值
            resolution=1,  # 步进值
            show=True,   # 是否在上面显示值
            orient=tk.HORIZONTAL,  # 水平显示
            length=680,  # 滑块长度
            # command=lambda value, key=k:self.get_value(value, key)
        )
        self.maxcloud_scale.grid(column=1,row=0,sticky='we')
        return

    def sleep_frame(self, row):
        frame=tkinter.ttk.Frame(self.window)
        frame.place(x=0,y=self.line_height*row)
        tk.Label(
            frame,text=f"间隔时长",font=('宋体','14','bold'),height=3,
        ).grid(column=0,row=0,sticky='we')
        sleep = tk.IntVar()
        sleep.set(15)
        self.sleep_scale=tk.Scale(
            frame, 
            # label="MaxCloud",    # 标签
            variable=sleep, 	# 值
            from_=0,    #  最小值， 记住是from_， from是关键字
            to=120,       #  最大值
            resolution=1,  # 步进值
            show=True,   # 是否在上面显示值
            orient=tk.HORIZONTAL,  # 水平显示
            length=680,  # 滑块长度
            # command=lambda value, key=k:self.get_value(value, key)
        )
        self.sleep_scale.grid(column=1,row=0,sticky='we')
        return

    def acount_frame(self, row):
        frame=tkinter.ttk.Frame(self.window,width=self.width)
        frame.place(x=0,y=self.line_height*row)
        column_iter = iter(range(10))
        tk.Label(
            frame,text="选择账户",font=('宋体','14','bold'),height=3,
        ).grid(column=next(column_iter),row=0,sticky=tk.W+tk.E)

        self.username=tkinter.ttk.Combobox(
            frame,
            # width=4,
            height=len(list(account_infos.keys())),
            state='readonly',
            cursor="arrow",
            background = 'white',
            textvariable="",  # 必须为空
            font = ('', '12', ''),
            values=tuple(list(account_infos.keys())),
            show=None
        )
        self.username.current(0)
        self.username.grid(column=next(column_iter),row=0,sticky='we')
        return

    def config_frame(self, row):
        frame=tkinter.ttk.Frame(self.window,width=self.width)
        frame.place(x=0,y=self.line_height*row)
        column_iter = iter(range(10))

        tk.Label(
            frame,text="配置文件",font=('宋体','14','bold'),height=3,
            ).grid(column=next(column_iter),row=0,sticky='we')
        self.jsonfile_entry=tk.Entry(
            frame,
            width=74,
            background = 'white',
            borderwidth = 3,
            relief = 'sunken',
            insertwidth = 3,
            font = ('宋体', '12', ''),
            textvariable=self.config_path,
            selectforeground = 'red',
            selectbackground = 'blue',
            selectborderwidth = 0,
            show=None, 
        )
        self.jsonfile_entry.grid(column=next(column_iter),row=0,sticky='we')
        self.select_file_button=tk.Button(
            frame,
            text="选择文件",
            font=('','14','bold'), 
            bg="#50b7c1",
            command=lambda:
                self.config_path.set(
                    filedialog.askopenfilename(filetypes=[("配置文件", [".txt",])])
                )
        ) 
        self.select_file_button.grid(column=next(column_iter),row=0,sticky='we')
        return

    def link_folder_frame(self, row):
        frame=tkinter.ttk.Frame(self.window)
        frame.place(x=0,y=self.line_height*row)
        column_iter = iter(range(10))
        tk.Label(
            frame,text="映射目录",font=('宋体','14','bold'),height=3
        ).grid(column=next(column_iter),row=0,sticky='we') 
        self.link_dir=tk.Entry(
            frame,
            width=74,
            background = 'white',
            borderwidth = 3,
            relief = 'sunken',
            insertwidth = 3,
            font = ('宋体', '12', ''),
            textvariable=self.link_folder,
            selectforeground = 'red',
            selectbackground = 'blue',
            selectborderwidth = 0,
            show=None, 
        )  
        self.link_dir.grid(column=next(column_iter),row=0,sticky='we')
        tk.Button(
            frame,
            text="选择目录",
            font=('','14','bold'), 
            bg="#50b7c1",
            command=lambda: self.link_folder.set(filedialog.askdirectory().replace('/','\\')),
        ).grid(column=next(column_iter),row=0,sticky='we')
        return

    def zip_folder_frame(self, row):
        frame=tkinter.ttk.Frame(self.window)
        frame.place(x=0,y=self.line_height*row)
        column_iter = iter(range(10))
        tk.Label(
            frame,text="远程目录",font=('宋体','14','bold'),height=3
        ).grid(column=next(column_iter),row=0,sticky='we') 
        self.local_dir=tk.Entry(
            frame,
            width=74,
            background = 'white',
            borderwidth = 3,
            relief = 'sunken',
            insertwidth = 3,
            font = ('宋体', '12', ''),
            textvariable=self.zip_folder,
            selectforeground = 'red',
            selectbackground = 'blue',
            selectborderwidth = 0,
            show=None, 
        )  
        self.local_dir.grid(column=next(column_iter),row=0,sticky='we')
        tk.Button(
            frame,
            text="选择目录",
            font=('','14','bold'), 
            bg="#50b7c1",
            command=lambda: self.zip_folder.set(filedialog.askdirectory().replace('/','\\')),
        ).grid(column=next(column_iter),row=0,sticky='we')
        return

    def send_data_frame(self, row):
        frame=tkinter.ttk.Frame(self.window)
        frame.place(x=0,y=self.line_height*row)
        column_iter = iter(range(10))

        tk.Label(
            frame,text="是否Link：",font=('宋体','14','bold'),height=3
        ).grid(column=next(column_iter),row=0,sticky='we') 

        self.send_flag = tk.IntVar()
        self.send_flag.set(1)
        tk.Checkbutton(
            frame,
            text="（非省份）",
            variable=self.send_flag,
        ).grid(column=next(column_iter),row=0,sticky='we')  
        # self.checkbutton_1
        # self.checkbutton_1.select()
        print()
        return

    def start_button_frame(self, row):
        frame=tkinter.ttk.Frame(
            self.window,width=self.width,height=60)
        frame.place(x=0,y=self.line_height*row)
        self.start_button=tk.Button(
            frame,
            text="开始下载",
            font=('','14','bold'),
            bg="#50b7c1",
            activebackground="red",
            activeforeground="blue",
            command=lambda: self.thread_it(self.run_main),
        )
        self.start_button.place(relx=0.5,rely=0.5,anchor='center')
        return

    def progressbar_frame(self,row):
        frame=tkinter.ttk.Frame(self.window,width=self.width)
        frame.place(x=0,y=self.line_height*row)
        column_iter = iter(range(10))

        tk.Label(
            frame,text="运行进度",font=('宋体','14','bold'),height=3,
        ).grid(column=next(column_iter),row=0,sticky='we')  

        self.progressbar = tkinter.ttk.Progressbar(
            frame,
            length=690,
            # maximum=100,
            value=0,
            cursor='spider',
            # mode="determinate",
            mode="indeterminate",
            orient=tk.HORIZONTAL,
        )
        self.progressbar.grid(column=next(column_iter),row=0,sticky='we')    
        return

    def print_running_frame(self, row):
        frame=tkinter.ttk.Frame(self.window)
        frame.place(x=0,y=self.line_height*row)
        column_iter = iter(range(5))
        tk.Label(
            frame,text="运行信息",font=('宋体','14','bold'),
        ).grid(column=next(column_iter),row=0,sticky='we')
        self.scrolled_text = scrolledtext.ScrolledText(
            frame, 
            state='normal',
            wrap = tk.WORD,
            # font=('Times New Roman', 12),
            font="TkFixedFont",
            width=98, 
            height=24,
        ) 
        self.scrolled_text.tag_config('INFO', foreground='black')
        self.scrolled_text.tag_config('DEBUG', foreground='gray')
        self.scrolled_text.tag_config('WARNING', foreground='orange')
        self.scrolled_text.tag_config('ERROR', foreground='red')
        self.scrolled_text.tag_config('CRITICAL', foreground='red', underline=1)
        self.scrolled_text.grid(column=next(column_iter),row=0,rowspan=20,sticky='we')
        # self.scrolled_text.pack(side=tk.LEFT,fill=tk.NONE) 
        return

    def thread_it(self,func,*args):
        # 线程
        t = threading.Thread(target=func, args=args)
        # 守护 !!!
        t.setDaemon(True)
        # 启动
        t.start()
        # 阻塞--卡死界面！
        # t.join()
        return

    def update_info(self,string):
        datetime_str = datetime.datetime.now().strftime('%H:%M:%S')
        string = f"{datetime_str}>{string} \n"
        self.scrolled_text.insert(tk.END, string)
        self.scrolled_text.see(tk.END)
        self.scrolled_text.focus()
        self.window.update()
        return

    def run_main(self):

        self.start_button.config({"state":tk.DISABLED})
        self.progressbar.start()
        start = time.time()
        self.scrolled_text.configure(state='normal')
        self.scrolled_text.delete(0.0, tkinter.END)
        self.window.update()

        tiles_str = self.tilestr_entry.get()
        if tiles_str == "":
            tk.messagebox.showwarning('Waring', '未选择下载图幅！')
            self.progressbar.stop()
            return self.start_button.config({"state":tk.NORMAL})
        tiles = [tile.upper() for tile in tiles_str.split("-")]
        self.update_info(f"下载图幅：{tiles}")

        try:
            start_date = datetime.date(
                int(self.start_year.get()), 
                int(self.start_month.get()), 
                int(self.start_day.get())
                ).strftime('%Y-%m-%d')
        except:
            tk.messagebox.showwarning('Waring', '未选择开始日期！')
            self.progressbar.stop()
            return self.start_button.config({"state":tk.NORMAL})
        self.update_info(f"下载开始日期：{start_date}")

        try:
            end_date = datetime.date(
                int(self.end_year.get()), 
                int(self.end_month.get()),
                int(self.end_day.get())
                ).strftime('%Y-%m-%d')
        except:
            tk.messagebox.showwarning('Waring', '未选择截至日期！')
            self.progressbar.stop()
            return self.start_button.config({"state":tk.NORMAL})
        self.update_info(f"下载截至日期：{end_date}")

        thread_sum = self.thread_scale.get()
        self.update_info(f"最大线程量：{thread_sum}个")

        max_cloud = self.maxcloud_scale.get()
        self.update_info(f"最大含云量：{max_cloud}%")

        sleep = self.sleep_scale.get()
        self.update_info(f"间隔时长：{sleep}s")

        if self.username.get() == "请选择ESA账号":
            tk.messagebox.showwarning('Waring', '未选择ESA账号！')
            self.progressbar.stop()
            return self.start_button.config({"state":tk.NORMAL})
        esa_username,esa_password = self.username.get(),account_infos[self.username.get()]
       
        self.update_info(f"ESA账户信息：{self.username.get()}")


        os.system(r"net use Z: \\192.168.2.172\root DELL123dell /user:root /PERSISTENT:YES")

        local_dir = self.local_dir.get()
        if not os.path.exists(local_dir):
            print(local_dir)
            tk.messagebox.showwarning('Waring', '未选择挂载目录！')
            self.progressbar.stop()
            return self.start_button.config({"state":tk.NORMAL})
        self.update_info(f"挂载目录：{local_dir}")

        link_dir = self.link_dir.get()
        
        if not os.path.exists(link_dir):
            self.update_info(f"Waring：未选择本地目录！")
        else:
            self.update_info(f"本地目录：{link_dir}")

        self.update_info(f"正在查询172服务器已存在的数据......")
        exists = check_sentinel2_in172([
            "192.168.2.172",
            22,
            "root",
            "DELL123dell",
            tiles,
            start_date,
            end_date,
            r"/home/万裕青/遥感数据/Sentinel2L1cZip"
        ])
        for exist in exists:
            self.update_info(f"{exist} Exist!")

        self.update_info(f"正在从ESA上查询并下载数据......")  
        zip_paths = sentinel2_downloader([
            esa_username,
            esa_password,
            tiles,
            start_date,
            end_date,
            max_cloud,
            exists,
            local_dir,
            thread_sum,
            sleep
        ])

        province = self.province_combobox.get()

        if province != "请选择省份（非必须）":
            self.update_info(f"正在映射ZIP文件......")  
            province_dir = os.path.join(link_dir, province)
            if not os.path.exists(province_dir):
                os.makedirs(province_dir)
            remote_province_dir = str(pathlib.PurePosixPath(
                r"/home/万裕青/遥感数据",
                os.path.basename(link_dir),
                province
            ))
            zip_file_link([ 
                "192.168.2.172",
                22,
                "root",
                "DELL123dell",
                zip_paths,
                remote_province_dir
            ])

        elif os.path.basename(link_dir) in list(account_infos.keys()):
            province_dir = link_dir
            self.update_info(f"正在映射ZIP文件......")
            if not os.path.exists(province_dir):
                os.makedirs(province_dir)
            remote_province_dir = str(pathlib.PurePosixPath(
                r"/home/万裕青/遥感数据",
                os.path.dirname(province_dir)[2:].replace("\\","/"),
            ))
            zip_file_link([ 
                "192.168.2.172",
                22,
                "root",
                "DELL123dell",
                zip_paths,
                remote_province_dir
            ])
        else:
             self.update_info(f"无法映射ZIP文件......")


        self.progressbar.stop()
        tk.messagebox.showinfo('Message', f'下载完成！耗时：{time.time()-start}')
        self.start_button.config({"state":tk.NORMAL})
        return



if __name__ == "__main__":
    my_ui()

    # tiles = china_tiles["河南省"]
    # start_date,end_date='2022-01-01','2022-01-31'
    # exists = check_sentinel2_in172([
    #         "192.168.2.172",
    #         22,
    #         "root",
    #         "DELL123dell",
    #         tiles,
    #         start_date,
    #         end_date,
    #         r"/home/万裕青/遥感数据/Sentinel2L1cZip"
    #     ])
    # username,password="fyy001", "show1234"
   
    # max_cloud=100
  
    # folder=r"G:\河南6"
    # n_concurrent_dl=1
    # sentinel2_downloader([username,password,tiles,start_date,end_date,max_cloud,exists,folder,n_concurrent_dl])
	
	